package de.luh.slimpp

import de.luh.slimpp.slimPP.ClassDefinition
import de.luh.slimpp.slimPP.TypeName
import java.util.HashSet

class CodeGenerator {

	InternalTypeDatabase internal

	new(InternalTypeDatabase internal) {
		this.internal = internal
	}

	def getInclues(ClassDefinition cls) {
		val forwards = new HashSet<String>
		val includes = new HashSet<String>

		// first of all include all base classes
		for (base : cls.bases) {
//			includes.add(base.qualifiedName.full)
		}

		// find all referenced types in the whole class
		for (t : cls.eAllContents.toIterable.filter(typeof(TypeName))) {

			if (!t.unsigned) {

				// unsigned long/int/... are native types and do not need a header so we do not consider them
				var type = t.type // the type may contain template arguments or be a namespace
				var name = type.name // this is going to hold the whole qualified type name

				// if hasNext is true this type.name is actually a namespace so we just add it
				// EXCEPT if the template argument exists in which case type.name is a class (and the template
				// is handled by another run of the for-loop)
				while (type.hasNext && type.templateArgument == null) {
					type = type.nextType
					name = name + '.' + type.name
				}

				// now if this is a pointer type we can forward declare it
				if (type.pointer == null)
					forwards.add(name)
				else
					includes.add(name)
			}
		}

		// TODO find all headers already included in the base classes and do not include them again 
		
		// if a type is included we do not need to forward it anymore
		includes.forEach[forwards.remove(it)]
	}
}
